package com.wjb.xietong.ota.tab4;

import java.io.File;
import java.lang.reflect.Method;
import java.util.Timer;
import java.util.TimerTask;

import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageStatsObserver;
import android.content.pm.PackageManager;
import android.content.pm.PackageStats;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.StatFs;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.RelativeLayout;

import com.wjb.xietong.R;
import com.wjb.xietong.ota.BaseOTA;
import com.wjb.xietong.util.LogD;
import com.wjb.xietong.util.PreferencesService;
import com.wjb.xietong.view.CVSwitch;
import com.wjb.xietong.view.CVSwitch.OnCheckedChangeListener;

public class OTASystemSetting extends BaseOTA {
	PreferencesService share = new PreferencesService(this);
	private static final String PACKAGENAME = "com.wjb";

	private Handler mHandler = null;// 用来更新Toast信息
	// Handler中可以处理的Message
	private static final int MSG_UPDATE_TOAST_TEXT = 1;// 更新Toast显示的信息

	private long cacheSize = 0l;// 记录手机中缓存的大小

	private PackageManager mPackageManager = null;// 在处理缓存相关的函数中使用

	private boolean flymode = false;
	private boolean total = false;

	private RelativeLayout btn_flymode;

	private Button btn_clearcache;

	private CVSwitch totalSwitch;
	private CVSwitch flymodeSwitch;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentField(getLayoutInflater().inflate(
				R.layout.page_system_setting, null));

		setTopBarAndAction("系统设置", new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				app_.getActManager().popActivity();
			}
		}, null);

		mHandler = new Handler(Looper.getMainLooper()) {
			@Override
			public void handleMessage(Message msg) {// 处理msg
				switch (msg.what) {
				case MSG_UPDATE_TOAST_TEXT:
					// mText = String.format(formats[clear_set_index],
					// convertStorage(totalCacheSize));
					// mToast.setText(mText);
					btn_clearcache.setText("清理缓存(" + convertStorage(cacheSize)
							+ ")");
					break;
				}
			}
		};
	}

	@Override
	protected void findView(View v) {
		// TODO Auto-generated method stub
		super.findView(v);
		btn_flymode = (RelativeLayout) v.findViewById(R.id.flymode_lay);
		btn_clearcache = (Button) v.findViewById(R.id.btn_clearcache);
		totalSwitch = (CVSwitch) v.findViewById(R.id.total_switch);
		flymodeSwitch = (CVSwitch) v.findViewById(R.id.flymode_switch);
		total = share.getSettingPerference(PreferencesService.PREFERENCE_KEY_SETTING_TOTAL_SWITCH);
		flymode = share.getSettingPerference(PreferencesService.PREFERENCE_KEY_SETTING_MODE_SWITCH);
		setEnableStatusChange(total, flymode);
	}

	@Override
	protected void setOnClickEvent() {
		// TODO Auto-generated method stub
		super.setOnClickEvent();
		btn_clearcache.setOnClickListener(onclicklistener);
		totalSwitch.setOnCheckedChangeListener(oncheckedchangelistener);
		flymodeSwitch.setOnCheckedChangeListener(oncheckedchangelistener);
	}

	@Override
	protected void onResume() {
		super.onResume();
		try {
			queryPkgCacheSize(PACKAGENAME);
		} catch (Exception e) {
			LogD.output("Exception:" + e.getMessage());
		}
	}

	private void setEnableStatusChange(boolean totalEnable,
			boolean flymodeEnable) {
		totalSwitch.setChecked(totalEnable);
		flymodeSwitch.setChecked(flymodeEnable);
	}

	OnClickListener onclicklistener = new OnClickListener() {

		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			switch (v.getId()) {
			case R.id.btn_clearcache:
				if (mClearCacheTask != null) {
					mClearCacheTask.cancel();
				}
				mClearCacheTask = new ClearCacheTask();
				mTimer.schedule(mClearCacheTask, 0);
				// getpkginfo(PACKAGENAME);
				break;
			}
		}
	};

	OnCheckedChangeListener oncheckedchangelistener = new OnCheckedChangeListener() {

		@Override
		public void onCheckedChanged(CVSwitch sw, boolean isChecked) {
			// TODO Auto-generated method stub
			switch (sw.getId()) {
			case R.id.total_switch:
				LogD.output("onchecked" + isChecked);
				if (isChecked) {
					total = true;
				} else {
					total = false;
				}
				break;
			case R.id.flymode_switch:
				LogD.output("onchecked" + isChecked);
				if (isChecked) {
					flymode = true;
				} else {
					flymode = false;
				}
				break;
			default:
				break;
			}
			share.saveSettingMode(total, flymode);
		}

	};

	/**
	 * 执行清除缓存操作
	 * 
	 * @throws Exception
	 */
	private void clearCache() throws Exception {
		cacheSize = 0l;// 初始化
		queryPkgCacheSize(PACKAGENAME);// 给cacheSize赋值
		try {
			if (mPackageManager == null) {
				mPackageManager = app_.getPackageManager();// 得到被反射调用函数所在的类对象
			}
			String methodName = "freeStorageAndNotify";// 想通过反射机制调用的方法名
			Class<?> parameterType1 = Long.TYPE;// 被反射的方法的第一个参数的类型
			Class<?> parameterType2 = IPackageDataObserver.class;// 被反射的方法的第二个参数的类型
			Method freeStorageAndNotify = mPackageManager.getClass().getMethod(
					methodName, parameterType1, parameterType2);
			/*
			 * freeStorageSize ： The number of bytes of storage to be freed by
			 * the system. Say if freeStorageSize is XX, and the current free
			 * storage is YY, if XX is less than YY, just return. if not free
			 * XX-YY number of bytes if possible.
			 */
			Long freeStorageSize = Long.valueOf(getDataDirectorySize());

			freeStorageAndNotify.invoke(mPackageManager, freeStorageSize,
					new IPackageDataObserver.Stub() {
						@Override
						public void onRemoveCompleted(String packageName,
								boolean succeeded) throws RemoteException {
						}
					});
		} catch (Exception e) {
			LogD.output("Exception:" + e.getMessage());
		}
	}

	private Timer mTimer = new Timer();

	private TimerTask mClearCacheTask;

	class ClearCacheTask extends TimerTask {
		@Override
		public void run() {
			try {
				Thread.currentThread().sleep(50);
			} catch (InterruptedException e) {
				LogD.output("Exception:" + e.getMessage());
			}
			try {
				clearCache();
			} catch (Exception e) {
				LogD.output("Exception:" + e.getMessage());
			}
		}
	}

	private void clearCacheSchedule() {
		if (mClearCacheTask != null) {
			mClearCacheTask.cancel();
		}
		mClearCacheTask = new ClearCacheTask();
		mTimer.schedule(mClearCacheTask, 0);
	}

	/**
	 * 返回/data目录的大小。
	 */
	private long getDataDirectorySize() {
		File tmpFile = Environment.getDataDirectory();
		if (tmpFile == null) {
			return 0l;
		}
		String strDataDirectoryPath = tmpFile.getPath();
		StatFs localStatFs = new StatFs(strDataDirectoryPath);
		long size = localStatFs.getBlockSize() * localStatFs.getBlockCount();
		return size;
	}

	/**
	 * 取得指定包名的程序的缓存大小
	 */
	private void queryPkgCacheSize(String pkgName) throws Exception {
		if (!TextUtils.isEmpty(pkgName)) {// pkgName不能为空
			// 使用放射机制得到PackageManager类的隐藏函数getPackageSizeInfo
			if (mPackageManager == null) {
				mPackageManager = app_.getPackageManager();// 得到被反射调用函数所在的类对象
			}
			try {
				// 通过反射机制获得该隐藏函数
				Method getPackageSizeInfo = mPackageManager.getClass()
						.getMethod("getPackageSizeInfo", String.class,// getPackageSizeInfo方法的参数类型
								IPackageStatsObserver.class);// getPackageSizeInfo方法的参数类型
				// 调用该函数，并且给其分配参数 ，待调用流程完成后会回调PkgSizeObserver类的函数
				getPackageSizeInfo.invoke(mPackageManager,// 方法所在的类
						pkgName, mStatsObserver);// 方法使用的参数

			} catch (Exception ex) {
				Log.wtf("tag", "queryPkgSize()-->NoSuchMethodException");
				LogD.output("Exception:" + ex.getMessage());
				throw ex; // 抛出异常
			}
		}
	}

	/**
	 * 使用Android系统中的AIDL文件，获得指定程序的大小。AIDL文件形成的Binder机制
	 */
	private IPackageStatsObserver.Stub mStatsObserver = new IPackageStatsObserver.Stub() {
		@Override
		public void onGetStatsCompleted(PackageStats pStats, boolean succeeded)
				throws RemoteException {
			cacheSize = pStats.cacheSize;
			mHandler.sendEmptyMessage(MSG_UPDATE_TOAST_TEXT);
		}
	};

	/**
	 * 将参数转化为GB、MB、KB、B的形式
	 */
	public static String convertStorage(long size) {
		long kb = 1024;
		long mb = kb * 1024;
		long gb = mb * 1024;

		if (size >= gb) {
			return String.format("%.1f GB", (float) size / gb);
		} else if (size >= mb) {
			float f = (float) size / mb;
			return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f);
		} else if (size >= kb) {
			float f = (float) size / kb;
			return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f);
		} else
			return String.format("%d B", size);
	}
}
